'Copyright (C) 2002 Microsoft Corporation
'All rights reserved.
'
'THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
'EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
'MERCHANTIBILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
'
'Date: June 2002
'Author: Duncan Mackenzie
'
'Requires the release version of .NET Framework

Imports System.Drawing

Namespace GraphicObjects

    <Serializable()> Public MustInherit Class GraphicObject

        Protected m_Position As New Point(0, 0)
        Protected m_Size As New Size(0, 0)
        Protected m_Rotation As Single = 0
        Protected m_AutoSize As Boolean = True
        Protected m_Container As GraphicObjectCollection

        Public Property Container() As GraphicObjectCollection
            Get
                Return m_Container
            End Get
            Set(ByVal Value As GraphicObjectCollection)
                m_Container = Value
            End Set
        End Property


        Public Overridable Overloads Function HitTest(ByVal pt As System.Drawing.Point) As Boolean
            Dim gp As New Drawing2D.GraphicsPath()
            Dim myMatrix As New Drawing2D.Matrix()

            gp.AddRectangle(New Rectangle(X, Y, Width, Height))
            If Me.Rotation <> 0 Then
                myMatrix.RotateAt(Me.Rotation, New PointF(Me.X, Me.Y), _
                    Drawing.Drawing2D.MatrixOrder.Append)
            End If

            gp.Transform(myMatrix)
            Return gp.IsVisible(pt)
        End Function

        Public Overridable Overloads Function HitTest(ByVal rect As Rectangle) As Boolean
            'is this object contained within the supplied rectangle
            Dim gp As New Drawing2D.GraphicsPath()
            Dim myMatrix As New Drawing2D.Matrix()

            gp.AddRectangle(New Rectangle(X, Y, Width, Height))
            If Me.Rotation <> 0 Then
                myMatrix.RotateAt(Me.Rotation, New PointF(Me.X, Me.Y), _
                    Drawing.Drawing2D.MatrixOrder.Append)
            End If
            gp.Transform(myMatrix)
            Dim gpRect As Rectangle = Rectangle.Round(gp.GetBounds)
            Return rect.Contains(gpRect)
        End Function


#Region "Constructors"
        Protected Sub New()
        End Sub

        Protected Sub New(ByVal graphicPosition As Point)
            Me.New()
            Me.SetPosition(graphicPosition)
        End Sub

        Protected Sub New(ByVal posX As Integer, ByVal posY As Integer)
            Me.New(New Point(posX, posY))
        End Sub

        Protected Sub New(ByVal graphicPosition As Point, ByVal graphicSize As Size)
            Me.New(graphicPosition)
            Me.SetSize(graphicSize)
            Me.AutoSize = False
        End Sub

        Protected Sub New(ByVal posX As Integer, ByVal posY As Integer, ByVal graphicSize As Size)
            Me.New(New Point(posX, posY), graphicSize)
        End Sub

        Protected Sub New(ByVal posX As Integer, ByVal posY As Integer, _
                ByVal width As Integer, ByVal height As Integer)
            Me.New(New Point(posX, posY), New Size(width, height))
        End Sub

        Protected Sub New(ByVal graphicPosition As Point, ByVal Rotation As Single)
            Me.New()
            Me.SetPosition(graphicPosition)
            Me.Rotation = Rotation
        End Sub

        Protected Sub New(ByVal posX As Integer, ByVal posY As Integer, ByVal Rotation As Single)
            Me.New(New Point(posX, posY), Rotation)
        End Sub

        Protected Sub New(ByVal graphicPosition As Point, ByVal graphicSize As Size, ByVal Rotation As Single)
            Me.New(graphicPosition, Rotation)
            Me.SetSize(graphicSize)
            Me.AutoSize = False
        End Sub

        Protected Sub New(ByVal posX As Integer, ByVal posY As Integer, _
            ByVal graphicSize As Size, ByVal Rotation As Single)
            Me.New(New Point(posX, posY), graphicSize, Rotation)
        End Sub

        Protected Sub New(ByVal posX As Integer, ByVal posY As Integer, ByVal width As Integer, _
                               ByVal height As Integer, ByVal Rotation As Single)
            Me.New(New Point(posX, posY), New Size(width, height), Rotation)
        End Sub

#End Region

        Public Overridable Property AutoSize() As Boolean
            Get
                Return m_AutoSize
            End Get
            Set(ByVal Value As Boolean)
                If Value <> m_AutoSize Then
                    m_AutoSize = Value
                End If
            End Set
        End Property
        Public Overridable Property X() As Integer
            Get
                Return m_Position.X
            End Get
            Set(ByVal Value As Integer)
                m_Position.X = Value
            End Set
        End Property

        Public Overridable Property Y() As Integer
            Get
                Return m_Position.Y
            End Get
            Set(ByVal Value As Integer)
                m_Position.Y = Value
            End Set
        End Property

        Public Overridable Function GetPosition() As Point
            Dim myPosition As New Point(m_Position.X, m_Position.Y)
            Return myPosition
        End Function

        Public Overridable Sub SetPosition(ByVal Value As Point)
            'any value is currently ok,
            'but I might want to add validation later.
            m_Position = Value
        End Sub

        Public Overridable Property Height() As Integer
            Get
                Return m_Size.Height
            End Get
            Set(ByVal Value As Integer)
                m_Size.Height = Value
            End Set
        End Property

        Public Overridable Property Width() As Integer
            Get
                Return m_Size.Width
            End Get
            Set(ByVal Value As Integer)
                m_Size.Width = Value
            End Set
        End Property

        Public Overridable Sub SetSize(ByVal Value As Size)
            m_Size = Value
        End Sub

        Private _id As Int32
        Public Overridable Property Id() As Integer
            Get
                Return _id
            End Get
            Set(ByVal Value As Integer)
                _id = Value
            End Set
        End Property

        Public Overridable Function GetSize() As Size
            Dim mySize As New Size(m_Size.Width, m_Size.Height)
            Return mySize
        End Function

        Public Overridable Property Rotation() As Single
            Get
                Return m_Rotation
            End Get
            Set(ByVal Value As Single)
                If System.Math.Abs(Value) < 360 Then
                    m_Rotation = Value
                Else
                    Throw New ArgumentOutOfRangeException("Rotation", _
                        "Rotation must be between -360.0 and 360.0")
                End If
            End Set
        End Property

        Public MustOverride Sub Draw(ByVal g As Graphics)

    End Class
End Namespace

